#include <iostream>
#include "contact.pb.h"
#include <string>
#include <fstream>

std::string file_name = "./contacts.txt";

void AddPeopleInfo(Contact::PeopleInfo* people)
{
    std::cout << "-------------新增联系⼈-------------" << std::endl;
    std::cout << "请输⼊联系⼈姓名: ";
    std::string name;
    std::getline(std::cin, name);
    people->set_name(name);
    std::cout << "请输⼊联系⼈年龄: ";
    int age;
    std::cin >> age;
    people->set_age(age);

    // 去除换行符
    std::cin.ignore(256, '\n');

    for(int i = 1; ; i++) 
    {
        std::cout << "请输⼊联系⼈电话" << i << "(只输入回车完成电话新增): ";
        std::string number;
        std::getline(std::cin, number);
        if (number.empty()) 
            break;
        Contact::PeopleInfo_Phone* phone = people->add_phone();
        phone->set_phone(number);
        std::cout << "请输入电话的类型(1. 移动电话   2.固定电话) : ";
        int phone_type = 0;
        std::cin >> phone_type;
        std::cin.ignore(256, '\n');
        switch(phone_type)
        {
            case 1: phone->set_type(Contact::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2: phone->set_type(Contact::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default : phone->set_type(Contact::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_Other);
                break;
        }   
    }
    // 添加联系人地址
    Contact::Address addr;
    std::cout << "请输入联系人的家庭地址: ";
    std::string home;
    getline(std::cin, home);
    addr.set_home_addr(home);
    std::cout << "请输入联系人的工作地址: ";
    std::string work;
    getline(std::cin, work);
    addr.set_work_addr(work);
    // 这里把Address类型转化为any类型放入
    people->mutable_address()->PackFrom(addr);

    std::cout << "请选择你要添加的(1. qq    2. 微信) : ";
    int input = 0;
    std::cin >> input;
    std::cin.ignore(256, '\n');
    std::string str;
    switch(input)
    {
        case 1: std::cout << "请输入qq信息: ";
            getline(std::cin, str);
            people->set_qq(str);
            break;
        case 2 : std::cout << "请输入微信信息: ";
            getline(std::cin, str);
            people->set_wx(str);
            break;
        default : break;
    }

    for(int i = 0; ; i++)
    {
        std::cout << "请输入联系人的其他备注类型(换行退出) " << i + 1 << " : ";
        std::string key;
        getline(std::cin, key);
        if(key.empty()) break;
        std::string info;
        std::cout << "请输入备注信息 : ";
        getline(std::cin, info);
        people->mutable_info()->insert({key, info});
    }

    std::cout << "-----------添加联系⼈成功-----------" << std::endl;
}

int main()
{
    Contact::ContactsInfo contacts;
    // 首先先读取文件中的通讯录信息保存到contacts中
    // 这里以二进制的方式打开文件 因为protobuf序列化之后数据是二进制形式的
    std::fstream input(file_name, std::ios::in | std::ios::binary);
    if(!input.is_open())
    {
        std::cout << "联系人信息为空 等待添加新的联系人" << "\n";
    }
    else 
    {
        // 之前的文件中有联系人的信息 直接进行反序列化读取数据
        if(!contacts.ParseFromIstream(&input))
        {
            std::cout << "联系人信息反序列化失败 退出" << "\n";
            input.close();
            return -1;
        }
        else 
        {
            std::cout << "联系人信息读取成功" << "\n";
        }
    }

    input.close();

    // 添加联系人信息 返回的空间进行添加
    
    AddPeopleInfo(contacts.add_people());

    // 吧联系人的信息重新覆盖写入到文件中
    std::fstream output(file_name, std::ios::out | std::ios::binary | std::ios::trunc);
    if(!output.is_open())
    {
        std::cout << "联系人信息文件打开失败" << "\n";
        output.close();
        return -2;
    }
    else 
    {
        if(!contacts.SerializeToOstream(&output))
        {
            std::cout << "联系人信息写入失败" << "\n";
            output.close();
            return -3;
        }
        else 
        {
            std::cout << "联系人信息添加成功" << "\n";
        }
    }
    output.close();

    return 0;
}
